﻿using Furion.DatabaseAccessor;
using Furion.DataEncryption;
using Furion.DependencyInjection;
using Queer.Cache;
using Queer.Entity;
using Queer.Enum;
using Queer.Enum.OrganizationManage;
using Queer.IBusiness.OrganizationManage;
using Queer.IService.OrganizationManage;
using Queer.IService.SystemManage;
using Queer.Model.Param.OrganizationManage;
using Queer.Util;
using Queer.Util.Helper;
using Queer.Util.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Queer.Business.OrganizationManage
{
    /// <summary>
    /// 创 建：song
    /// 日 期：2020-12-04 12:41
    /// 描 述：用户信息业务类
    /// </summary>

    public class UserBLL : IUserBLL, ITransient
    {
        private IUserService _userService;
        private IUserBelongService _userBelongService;
        private IRoleService _roleService;
        private IPositionService _positionService;
        private IDepartmentService _departmentService;
        private OperatorCache _operatorCache;

        public UserBLL(IUserService userService, IUserBelongService userBelongService, IRoleService roleService, IPositionService positionService,
            IDepartmentService departmentService, OperatorCache operatorCache)
        {
            _userService = userService;
            _userBelongService = userBelongService;
            _roleService = roleService;
            _positionService = positionService;
            _departmentService = departmentService;
            _operatorCache = operatorCache;
        }


        private List<DepartmentEntity> Main = new List<DepartmentEntity>();

        #region 获取数据

        public async Task<TData<List<UserEntity>>> GetList(UserListParam param)
        {
            TData<List<UserEntity>> obj = new TData<List<UserEntity>>();
            obj.Data = await _userService.GetList(param);
            obj.Tag = 1;
            return obj;
        }

        public async Task<TData<List<UserEntity>>> GetPageList(UserListParam param, Pagination pagination)
        {
            TData<List<UserEntity>> obj = new TData<List<UserEntity>>();
            obj.Data = await _userService.GetPageList(param, pagination);

            obj.Total = pagination.TotalCount;
            obj.Tag = 1;
            return obj;
        }

        public async Task<TData<UserEntity>> GetEntity(long id)
        {
            TData<UserEntity> obj = new TData<UserEntity>();
            obj.Data = await _userService.GetEntity(id);
            obj.Tag = 1;
            return obj;
        }

        /// <summary>
        /// 登陆校验
        /// </summary>
        public async Task<TData<UserEntity>> CheckLogin(string userName, string password)
        {
            TData<UserEntity> obj = new TData<UserEntity>();
            if (userName.IsEmpty() || password.IsEmpty())
            {
                obj.Message = "用户名或密码不能为空";
                return obj;
            }

            UserEntity user = await _userService.CheckLogin(userName);
            if (user != null)
            {
                if (user.UserStatus == (int)StatusEnum.Yes)
                {
                    if (user.Password == EncryptUserPassword(password, user.Salt))
                    {
                        user.IsOnline = 1;
                        user.LastVisit = DateTime.Now;
                        user.LoginCount = user.LoginCount.GetValueOrDefault() + 1;
                        user.PreviousVisit = user.LastVisit;
                        user.ApiToken = SecurityHelper.GetGuid();

                        if (!user.FirstVisit.HasValue)
                            user.FirstVisit = user.LastVisit;

                        await GetUserBelong(user);

                        await _userService.SaveForm(user);

                        obj.Data = user;
                        obj.Message = "登录成功";
                        obj.Tag = 1;
                    }
                    else
                        obj.Message = "密码不正确，请重新输入";
                }
                else
                    obj.Message = "账号被禁用，请联系管理员";
            }
            else
                obj.Message = "账号不存在，请重新输入";

            return obj;


        }

        public async Task<TData<object>> UserPageLoad()
        {
            TData<object> data = new TData<object>();
            List<RoleEntity> roles = await _roleService.GetList(null);
            List<PositionEntity> positions = await _positionService.GetList(null);

            #region 部门信息

            List<DepartmentEntity> departmentList = await _departmentService.GetList(null);
            OperatorInfo operatorInfo = await _operatorCache.Current();
            List<long> childrenDepartmentIdList = await GetChildrenDepartmentIdList(departmentList, operatorInfo.DepartmentId.Value);

            departmentList = departmentList.Where(p => childrenDepartmentIdList.Contains(p.Id.Value)).ToList();

            Main.Add(departmentList.Where(x => x.ParentId.GetValueOrDefault() == 0).FirstOrDefault());//根节点
            AddDepartment(departmentList, Main.FirstOrDefault());//递归

            //结果树形结构
            List<DepartmentEntity> treeMenu = Main;

            #endregion

            data.Tag = 1;
            data.Data = new { roles, positions, ztreeInfo = treeMenu };
            return data;
        }


        /// <summary>
        /// 获取用户的职位和角色
        /// </summary>
        /// <param name="user"></param>
        public async Task GetUserBelong(UserEntity user)
        {
            List<UserBelongEntity> userBelongList = await _userBelongService.GetList(new UserBelongListParam { UserId = user.Id });

            List<UserBelongEntity> roleBelongList = userBelongList.Where(p => p.BelongType == UserBelongTypeEnum.Role.ParseToInt()).ToList();
            if (roleBelongList.Count > 0)
                user.RoleIds = string.Join(",", roleBelongList.Select(p => p.BelongId).ToList());

            List<UserBelongEntity> positionBelongList = userBelongList.Where(p => p.BelongType == UserBelongTypeEnum.Position.ParseToInt()).ToList();
            if (positionBelongList.Count > 0)
                user.PositionIds = string.Join(",", positionBelongList.Select(p => p.BelongId).ToList());

        }

        #endregion

        #region 提交数据

        /// <summary>
        /// 保存用户信息
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        [UnitOfWork]
        public async Task<TData<string>> SaveForm(UserEntity entity)
        {
            TData<string> obj = new TData<string>();

            if (entity.IsSystem == 1)
                throw new BusinessException("禁止操作！");

            entity.Password = GlobalContext.SystemConfig.DefaultUserPWD;
            entity.UserStatus = 1;
            entity.Salt = GetPasswordSalt();
            entity.Password = EncryptUserPassword(entity.Password, entity.Salt);

            // 保存用户信息
            await _userService.SaveForm(entity);

            // 保存角色和职位信息
            await _userBelongService.DeleteByUserId(entity.Id.Value);
            if (!entity.RoleIds.IsEmpty())
                await _userBelongService.SaveUserRoles(entity.Id.Value, entity.RoleIds.Split(",").Select(a => a.ParseToLong()).ToList());
            if (!entity.PositionIds.IsEmpty())
                await _userBelongService.SaveUserPositions(entity.Id.Value, entity.PositionIds.Split(",").Select(a => a.ParseToLong()).ToList());

            obj.Data = entity.Id.ParseToString();
            obj.Tag = 1;
            return obj;
        }

        public async Task<TData> DeleteForm(string ids)
        {
            TData obj = new TData();
            await _userService.DeleteForm(ids);
            obj.Tag = 1;
            return obj;
        }

        /// <summary>
        /// 修改用户状态
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task<TData> ChangeUserState(UserEntity entity)
        {
            await _userService.ChangeUserState(entity);

            TData data = new TData();
            data.Tag = 1;
            return data;
        }

        public async Task<TData<long>> ResetPassword(UserEntity entity)
        {
            TData<long> obj = new TData<long>();

            if (entity.Id > 0)
            {
                if (string.IsNullOrWhiteSpace(entity.Password))
                    throw new BusinessException("参数不合法");

                entity.Salt = GetPasswordSalt();
                entity.Password = EncryptUserPassword(entity.Password, entity.Salt);
                await _userService.ResetPassword(entity);
                obj.Data = entity.Id.Value;
                obj.Tag = 1;
            }
            else
                throw new BusinessException("参数不合法");

            return obj;
        }
        #endregion

        #region 私有方法

        /// <summary>
        /// 密码MD5处理
        /// </summary>
        /// <param name="password"></param>
        /// <param name="salt"></param>
        /// <returns></returns>
        private string EncryptUserPassword(string password, string salt)
        {
            string md5Password = MD5Encryption.Encrypt(password);
            string encryptPassword = MD5Encryption.Encrypt(md5Password + salt);
            return encryptPassword;
        }

        /// <summary>
        /// 密码盐
        /// </summary>
        /// <returns></returns>
        private string GetPasswordSalt()
        {
            return new Random().Next(1, 100000).ToString();
        }

        /// <summary>
        /// 获取当前部门及下面所有的部门
        /// </summary>
        /// <param name="departmentList"></param>
        /// <param name="departmentId"></param>
        /// <returns></returns>
        public async Task<List<long>> GetChildrenDepartmentIdList(List<DepartmentEntity> departmentList, long departmentId)
        {
            if (departmentList == null)
            {
                departmentList = await _departmentService.GetList(null);
            }
            List<long> departmentIdList = new List<long>();
            departmentIdList.Add(departmentId);
            GetChildrenDepartmentIdList(departmentList, departmentId, departmentIdList);
            return departmentIdList;
        }

        /// <summary>
        /// 获取该部门下面所有的子部门
        /// </summary>
        /// <param name="departmentList"></param>
        /// <param name="departmentId"></param>
        /// <param name="departmentIdList"></param>
        private void GetChildrenDepartmentIdList(List<DepartmentEntity> departmentList, long departmentId, List<long> departmentIdList)
        {
            var children = departmentList.Where(p => p.ParentId == departmentId).Select(p => p.Id.Value).ToList();
            if (children.Count > 0)
            {
                departmentIdList.AddRange(children);
                foreach (long id in children)
                {
                    GetChildrenDepartmentIdList(departmentList, id, departmentIdList);
                }
            }
        }

        // 递归
        public void AddDepartment(List<DepartmentEntity> all, DepartmentEntity curItem)
        {
            if (curItem == null || !curItem.Id.HasValue) return;
            List<DepartmentEntity> childItems = all.Where(ee => ee.ParentId == curItem.Id).ToList(); //得到子节点
            curItem.children = childItems; //将子节点加入

            //遍历子节点，进行递归，寻找子节点的子节点
            foreach (var subItem in childItems)
            {
                AddDepartment(all, subItem);
            }
        }

        #endregion

    }
}